package com.xmhmyh.generalframework.framework.aspectj;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xmhmyh.generalframework.common.utils.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @Author: 于丁
 * @Description: 打印请求日志到控制台
 * @DateTime: 2020/7/21 5:23 下午
 * @Params:
 * @Return
 */
@Component
@Aspect
@Slf4j
public class HttpAspect {

    /**
     * 会话ID
     */
    private final static String SESSION_KEY = "sessionId";

    /**
     * @Author: 于丁
     * @Description: http拦截切点
     * @DateTime: 2019/12/23 1:24 下午
     * @Params:
     * @Return
     */
    @Around("com.xmhmyh.generalframework.framework.aspectj.pointCut.HttpPointCut.httpPointCut()")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ServletUtils.getRequest();
        // 从切点上获取目标方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        String sessionId = request.getSession().getId();
        MDC.put(SESSION_KEY, sessionId);
        log.info("【============get a httpRequest==========】");
        // 请求URl
        log.info("【requestUrl】={}", request.getRequestURL());
        // 请求者IP
        log.info("【requestIP】={}", ServletUtils.getIPAddress());
        // 请求方法类型
        log.info("【requestMethodsType】={}", request.getMethod());
        // 请求方法
        log.info("【requestMethods】={}", methodSignature.getDeclaringTypeName() + '.' + methodSignature.getName());
        // sessionID
        log.info("【requestSessionID】={}", request.getSession().getId());
        // 方法参数
        log.info("【requestParams】={}", argsArrayToString(joinPoint.getArgs()));
        // 请求结果
        Object result = null;
        // 调用目标方法
        result = joinPoint.proceed();
        log.info("【requestResult】=" + JSONObject.toJSONString(result));
        MDC.remove(SESSION_KEY);
        return result;

    }
    /**
     * 判断是否需要过滤的对象。
     *
     * @param o 对象信息。
     * @return 如果是需要过滤的对象，则返回true；否则返回false。
     */
    public boolean isFilterObject(final Object o) {
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
    }
    /**
     * 参数拼装
     */
    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (int i = 0; i < paramsArray.length; i++) {
                if (paramsArray[i] == null) {
                    continue;
                }
                if (!isFilterObject(paramsArray[i])) {
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    params += jsonObj.toString() + " ";
                }
            }
        }
        return params.trim();
    }

}
